package frontend;

import DTRSFrontEnd.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.PortableServer.*;
import soenudp.Command;
import soenudp.UDPHelper;
import soenudp.UDPMessage;
import soenudp.UDPException;
import java.io.FileWriter;
import java.io.IOException;

public class FrontEndImpl extends FrontEndPOA {

    private String name;
    private static UDPHelper udpClient;
    private static String leader_ip;
    private static int leader_port;

    public FrontEndImpl(String city) {
        name = city;
        udpClient = new UDPHelper();
        try {
            udpClient.startUnicastClient("FRONT_END_" + name);
        } catch (UDPException e) {
            e.printStackTrace();
        }
        leader_ip = "localhost";
        leader_port = 20020;
    }

    public int check (String showID){
       UDPMessage response = sendToDTRS(new UDPMessage(showID, "", Command.CHECK, (long)0, (long)0, ""));
       log(response.toString());
       return (int)response.tickets;
    }

    public boolean reserve (int customerID, int numberOfTickets, String showID){
       UDPMessage response = sendToDTRS(new UDPMessage(showID, Integer.toString(customerID), Command.RESERVE, numberOfTickets, (long)0, ""));
       log(response.toString());
       return (response.command == Command.SUCCESS);
    }

    public boolean cancel (int customerID, int numberOfTickets, String showID){
       UDPMessage response = sendToDTRS(new UDPMessage(showID, Integer.toString(customerID), Command.CANCEL, numberOfTickets, (long)0, ""));
       log(response.toString());
       return (response.command == Command.SUCCESS);
    }

    public boolean exchange (int customerID, String reservedShowID, int reservedTickets, String desiredShowID, int desiredTickets){
       UDPMessage response = sendToDTRS(new UDPMessage(reservedShowID, Integer.toString(customerID), Command.EXCHANGE, reservedTickets, (long)0, "", desiredShowID, desiredTickets));
       log(response.toString());
       return (response.command == Command.SUCCESS);
    }

    private static UDPMessage sendToDTRS(UDPMessage request)
    {
        UDPMessage response = null;
        
        try 
        {
            udpClient.sendToNode(leader_ip, leader_port, request);
            response = udpClient.getMessage();
        } catch (UDPException e) 
        {
            e.printStackTrace();
        }
        
        return response;
    }

    public static void main(String[] args) {
        try {
            //create and initialize ORB
            ORB orb = ORB.init(args, null);

            // get reference to rootpoa & activate the POAManager
            POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
            rootpoa.the_POAManager().activate();
            String city = args[0];

            //instantiate
            FrontEndImpl fe = new FrontEndImpl(city);
            //register
            org.omg.CORBA.Object ref = rootpoa.servant_to_reference(fe);
            FrontEnd feref = FrontEndHelper.narrow(ref);
            //get root naming context
            org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
             NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
             // bind the Object reference in naming
             NameComponent path[] = ncRef.to_name( city );
             ncRef.rebind(path, feref);
             System.out.println(city + " front end ready and waiting ...");
             //wait for invocations from clients
             orb.run();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
             
    }

    private void log(String msg) {
        //System.out.println(msg);
        
	FileWriter logger;
	try {
	    logger = new FileWriter(name + ".log", true);//TOR.log, MTL.log, VAN.log...
	    logger.write(msg + "\n");
            logger.close();
	}
	catch (IOException e) {
	    System.err.println("IO Exception");
	    e.printStackTrace();
	}
        
    }
}
